package org.emet.service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.emet.dao.ash.AshHallDao;
import org.emet.dao.ash.AshItemDao;
import org.emet.dao.ash.FrameDao;
import org.emet.dao.ash.StorageInfoDao;
import org.emet.entity.ash.AshHall;
import org.emet.entity.ash.AshItem;
import org.emet.entity.ash.Frame;
import org.emet.entity.ash.StorageInfo;
import org.emet.jee.BusinessException;
import org.emet.jee.console.dao.security.UserDao;
import org.emet.jee.console.entity.security.User;
import org.emet.jee.core.dao.Page;
import org.emet.jee.core.security.springsecurity.SpringSecurityUtils;
import org.emet.service.dto.ash.AshItemSearchCriteria;
import org.emet.service.dto.ash.StorageInfoSearchCriteria;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class AshStorageService {
	private static final Logger logger = LoggerFactory.getLogger(AshStorageService.class);

	@Autowired
	private AshHallDao ashHallDao;
	@Autowired
	private FrameDao frameDao;
	@Autowired
	private StorageInfoDao storageInfoDao;
	@Autowired
	private AshItemDao ashItemDao;
	@Autowired
	private UserDao userDao;

	@Secured("A_MODIFY_STORAGE")
	public void saveHall(AshHall hall) {
		String hql = "select count(*) from AshHall where  code = :CODE";
		Map<String, Object> m = new LinkedHashMap<String, Object>();
		m.put("CODE", hall.getCode());
		if (hall.getId() != null) {
			hql += " and id <> :ID ";
			m.put("ID", hall.getId());
		}

		long count = ashHallDao.findUnique(hql, m);
		if (count > 0)
			throw new BusinessException("已经存在相同的代码！");

		try {
			ashHallDao.save(hall);
		} catch (Exception e) {
			final String message = "保存寄室时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_VIEW_STORAGE")
	@Transactional(readOnly = true)
	public List<AshHall> getAllHalls() {
		return ashHallDao.getAll("code", true);
	}

	@Secured("A_VIEW_STORAGE")
	@Transactional(readOnly = true)
	public AshHall getHall(long id) {
		try {
			return ashHallDao.get(id);
		} catch (Exception e) {
			String message = "获取寄存厅信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);

		}
	}

	@Secured("A_MODIFY_STORAGE")
	public void deleteHall(long id) {
		try {
			ashHallDao.delete(id);
		} catch (Exception e) {
			String message = "删除寄存厅信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_MODIFY_STORAGE")
	public void saveFrame(Frame frame) {
		String hql = "select count(*) from Frame where  code = :CODE";
		Map<String, Object> m = new LinkedHashMap<String, Object>();
		m.put("CODE", frame.getCode());
		if (frame.getId() != null) {
			hql += " and id <> :ID ";
			m.put("ID", frame.getId());
		}

		long count = frameDao.findUnique(hql, m);
		if (count > 0)
			throw new BusinessException("已经存在相同的代码！");
		try {
			frameDao.save(frame);
		} catch (Exception e) {
			String message = "保存架位信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_VIEW_STORAGE")
	@Transactional(readOnly = true)
	public Frame getFrame(long id) {
		try {
			return frameDao.get(id);
		} catch (Exception e) {
			String message = "获取架位信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	public List<Frame> getFrames(Long hallId) {
		try {
			return frameDao.find("from Frame where ashHall.id=?", hallId);
		} catch (Exception e) {
			String message = "获取架位信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	public List<AshItem> getAshItems(Long frameId) {
		try {
			return frameDao.find("from AshItem where frame.id=?", frameId);
		} catch (Exception e) {
			String message = "获取信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	public List<AshItem> getAshItemsByHall(Long hallId) {
		try {
			return frameDao.find("from AshItem where frame.ashHall.id=?", hallId);
		} catch (Exception e) {
			String message = "获取信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_MODIFY_STORAGE")
	public void deleteFrame(long id) {
		try {
			frameDao.delete(id);
		} catch (Exception e) {
			String message = "删除架位信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_VIEW_STORAGE")
	@Transactional(readOnly = true)
	public List<AshItem> getAshItemRow(long frameId, int rowNo) {
		try {
			return frameDao.getAshItemRow(frameId, rowNo);
		} catch (Exception e) {
			String message = "获取信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_MODIFY_STORAGE")
	public void saveAshItem(AshItem item) {
		String hql = "select count(*) from AshItem where  code = :CODE and frame.id = " + item.getFrame().getId();
		Map<String, Object> m = new LinkedHashMap<String, Object>();
		m.put("CODE", item.getCode());
		if (item.getId() != null) {
			hql += " and id <> :ID ";
			m.put("ID", item.getId());
		}
		long count = frameDao.findUnique(hql, m);
		if (count > 0)
			throw new BusinessException("已经存在相同的代码！");

		try {
			ashItemDao.save(item);
		} catch (Exception e) {
			String message = "保存信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_VIEW_STORAGE")
	@Transactional(readOnly = true)
	public AshItem getAshItem(long id) {
		try {
			return ashItemDao.get(id);
		} catch (Exception e) {
			String message = "获取信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_MODIFY_STORAGE")
	public void deleteAshItem(long id) {
		try {
			ashItemDao.delete(id);
		} catch (Exception e) {
			String message = "删除时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_MODIFY_STORAGE")
	public void saveStorageInfo(StorageInfo info) {
		if (info.isAudit())
			throw new BusinessException("信息已经审核不能修改!");

		Long ashItemId = info.getAshItemId();
		if (ashItemId != null) {
			AshItem ashItem = ashItemDao.get(ashItemId);
			ashItem.setStatus(2);
			ashItem.setdName(info.getDeceasedName());
		}

		try {
			storageInfoDao.save(info);
		} catch (Exception e) {
			String message = "保存寄存信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_AUDIT_STORAGE")
	public void audit(long id) {
		StorageInfo storageInfo = storageInfoDao.get(id);
		if (storageInfo == null)
			throw new BusinessException("该信息可能已经被其它用户删除！");

		if (!storageInfo.isAudit()) {
			storageInfo.setAudit(true);

			String currentUserName = SpringSecurityUtils.getCurrentUserName();
			User user = userDao.findUniqueBy("loginName", currentUserName);
			// 设置审核人相关的信息
			storageInfo.setAuditUserSN(user.getStaffNumber());
			storageInfo.setAuditUser(user.getName());
		}
	}

	@Secured("A_MODIFY_STORAGE")
	public void deleteStorage(Long id) {
		final StorageInfo info = storageInfoDao.get(id);
		if (info == null)
			throw new BusinessException("该信息可能已经被其它用户删除！");

		if (info.isAudit())
			throw new BusinessException("信息已经审核不能修改!");

		Long ashItemId = info.getAshItemId();
		if (ashItemId != null) {
			AshItem ashItem = ashItemDao.get(ashItemId);
			if (ashItem != null) {
				ashItem.setStatus(0);
				ashItem.setdName(null);
			}
		}

		try {
			storageInfoDao.delete(id);
		} catch (Exception e) {
			String message = "保存寄存信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Secured("A_VIEW_STORAGE")
	@Transactional(readOnly = true)
	public StorageInfo getStorageInfo(long id) {
		try {
			return storageInfoDao.get(id);
		} catch (Exception e) {
			String message = "获取寄存信息时发生错误！";
			logger.error(message, e);
			throw new BusinessException(message);
		}
	}

	@Transactional(readOnly = true)
	public StorageInfo getStorageInfoByAshItem(Long ashItemId) {
		List<StorageInfo> list = storageInfoDao.find("from StorageInfo where ashItemId=?", ashItemId);
		if (list.size() > 0)
			return list.get(0);
		return null;
	}

	@Transactional(readOnly = true)
	public java.sql.Date getNowDate() {
		return new java.sql.Date(new Date().getTime());
	}

	@Transactional(readOnly = true)
	public List<AshItem> searchAshItems(AshItemSearchCriteria criteria) {
		return ashItemDao.search(criteria);
	}

	@Transactional(readOnly = true)
	public Page<StorageInfo> searchStorageInfo(Page<StorageInfo> page, StorageInfoSearchCriteria c) {
		return storageInfoDao.search(page, c);
	}

	public AshItem getAshItemByCode(String code) {
		return ashItemDao.findUnique("from AshItem where code = ?", code);
	}

	public BigDecimal getAshItemPriceByCode(String code) {
		return ashItemDao.findUnique("select price from AshItem where code = ?", code);
	}

	public void takeAway(String person, String remark, Date date, Long id) {
		StorageInfo storageInfo = storageInfoDao.get(id);
		if (StringUtils.isBlank(person)) {
			storageInfo.setTakeAway(false);
		} else {
			storageInfo.setTakeAway(true);
		}
		storageInfo.setTakeAwayPerson(person);
		storageInfo.setTakeAwayDate(date);
		storageInfo.setTakeAwayRemark(remark);

		Long ashItemId = storageInfo.getAshItemId();
		if (ashItemId != null) {
			AshItem ashItem = ashItemDao.get(ashItemId);
			if (ashItem != null) {
				ashItem.setStatus(0);
				ashItem.setdName(null);
			}
		}

		storageInfoDao.save(storageInfo);
	}

}
